/********************************************************************************
 * MessagingSystemAction.java
 *
 * Created by Nishan Patel
 * Last modified Date: Nov 7, 2008 10:56:03 AM by Nishan Patel
 * Version : 0.1
 * Copyright (c) 2008 - 2009 cyberThink Infotech Pvt. Ltd., All rights reserved.
 ********************************************************************************/
package com.printeverywhere.action;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

import com.opensymphony.xwork2.ActionContext;
import com.printeverywhere.delegator.CommonFunctionDelegator;
import com.printeverywhere.delegator.MailServerDelegator;
import com.printeverywhere.dto.MailServer;
import com.printeverywhere.dto.MailingSystem;
import com.printeverywhere.dto.MessagingSystemCount;
import com.printeverywhere.dto.PrivateMailOption;
import com.printeverywhere.dto.User;
import com.printeverywhere.util.AdminConstants;
import com.printeverywhere.util.AttributeConstants;
import com.printeverywhere.util.MailHelper;
import com.printeverywhere.util.SearchCriteria;
import com.printeverywhere.util.SearchListCriteria;
import com.printeverywhere.util.SessionUtil;
import com.printeverywhere.util.Sort;
import com.printeverywhere.util.Validator;

public class MessagingSystemAction extends FrontBaseSupport implements ServletRequestAware {

	public MessagingSystemAction() {
		super(true, false);
		setMyAccount(true);
	}
	private HttpServletRequest request;

	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

	private final boolean messaging = true;

	/** The user. */
	private User user;

	/**  */
	private static final long serialVersionUID = 1L;

	/** Logger for this class. */
	private static final Logger logger = Logger.getLogger(MessagingSystemAction.class);

	private List<MailServer> mailList;

	private MailServer messageDetail;

	private MessagingSystemCount systemCount;

	private String show;

	private int pageSize = 25;

	private String parameter;

	/** The user id. */
	private Integer messageId;

	private Integer changeStatus;

	private Integer changeListStatus=0;

	private Date targetDate;

	private List<Criterion> criterionList = new ArrayList<Criterion>();
	
	private PrivateMailOption privateMailOption = new PrivateMailOption();

	public PrivateMailOption getPrivateMailOption() {
		return privateMailOption;
	}

	public void setPrivateMailOption(PrivateMailOption privateMailOption) {
		this.privateMailOption = privateMailOption;
	}

	public Integer getChangeListStatus() {
		return changeListStatus;
	}

	public void setChangeListStatus(Integer changeListStatus) {
		this.changeListStatus = changeListStatus;
	}

	public Integer getChangeStatus() {
		return changeStatus;
	}

	public void setChangeStatus(Integer changeStatus) {
		this.changeStatus = changeStatus;
	}

	public List<MailServer> getMailList() {
		return mailList;
	}

	public void setMailList(List<MailServer> mailList) {
		this.mailList = mailList;
	}

	public boolean isMessaging() {
		return messaging;
	}

	public void addListCriteriaByTime() throws Exception{
			if(changeListStatus ==1){
				DateFormat myDate = new SimpleDateFormat("yyyy-MM-dd hh:ss:mm".intern());
				Calendar cal = GregorianCalendar.getInstance();
				cal.add(Calendar.DATE, -1);
				String strDate = myDate.format(cal.getTime());
				targetDate = new SimpleDateFormat("yyyy-MM-dd hh:ss:mm".intern()).parse(strDate);
			}else if(changeListStatus == 2){
				DateFormat myDate = new SimpleDateFormat("yyyy-MM-dd hh:ss:mm".intern());
				Calendar cal = GregorianCalendar.getInstance();
				cal.add(Calendar.DATE, -7);
				String strDate = myDate.format(cal.getTime());
				targetDate = new SimpleDateFormat("yyyy-MM-dd hh:ss:mm".intern()).parse(strDate);
			}else if(changeListStatus == 3){
				DateFormat myDate = new SimpleDateFormat("yyyy-MM-dd hh:ss:mm".intern());
				Calendar cal = GregorianCalendar.getInstance();
				cal.add(Calendar.DATE, -14);
				String strDate = myDate.format(cal.getTime());
				targetDate = new SimpleDateFormat("yyyy-MM-dd hh:ss:mm".intern()).parse(strDate);
			}else if(changeListStatus == 4){
				DateFormat myDate = new SimpleDateFormat("yyyy-MM-dd hh:ss:mm".intern());
				Calendar cal = GregorianCalendar.getInstance();
				cal.add(Calendar.DATE, -31);
				String strDate = myDate.format(cal.getTime());
				targetDate = new SimpleDateFormat("yyyy-MM-dd hh:ss:mm".intern()).parse(strDate);
			}
	}

	public void mailBox() throws Exception {
		try{
			List<PrivateMailOption> list = (List<PrivateMailOption>) ActionContext.getContext().getApplication().get(AdminConstants.PRIVATE_MAIL_OPTIONS);
			if(list.size() > 0){
				privateMailOption = list.get(0);
				pageSize = privateMailOption.getDefaultMessagesPerPage();
			}
			user = (User) request.getSession().getAttribute(AttributeConstants.USER);
			systemCount = MailServerDelegator.getMessageCount(user.getId());

			if(show == null || show == "" || show.equalsIgnoreCase("inbox")){
				parameter="inbox";
				SearchListCriteria listCriteria = new SearchListCriteria();
				listCriteria.removeAllAttribute();
				listCriteria.setAttribute("userByUserId.id", new Object[] {user.getId(),listCriteria.EQ});
				if(changeListStatus != 0){
					addListCriteriaByTime();
					listCriteria.setAttribute("createdOn", new Object[] {targetDate,listCriteria.GE});
				}
				mailList = MailServerDelegator.getConditionMailList(listCriteria);
			}else if(show.equalsIgnoreCase("sent")){
				parameter="sent";
				SearchListCriteria listCriteria = new SearchListCriteria();
				listCriteria.removeAllAttribute();
				listCriteria.setAttribute("userByFromId.id", new Object[] {user.getId(),listCriteria.EQ});
				if(changeListStatus != 0){
					addListCriteriaByTime();
					listCriteria.setAttribute("createdOn", new Object[] {targetDate,listCriteria.GE});
				}
				mailList = MailServerDelegator.getConditionMailList(listCriteria);
			}else if(show.equalsIgnoreCase("unread")){
				parameter="unread";
				SearchListCriteria listCriteria = new SearchListCriteria();
				listCriteria.removeAllAttribute();
				listCriteria.setAttribute("userByUserId.id", new Object[] {user.getId(),listCriteria.EQ});
				listCriteria.setAttribute("isRead", new Object[] {false,listCriteria.EQ});
				if(changeListStatus != 0){
					addListCriteriaByTime();
					listCriteria.setAttribute("createdOn", new Object[] {targetDate,listCriteria.GE});
				}
				mailList = MailServerDelegator.getConditionMailList(listCriteria);
			}else if(show.equalsIgnoreCase("flagged")){
				parameter="flagged";
				SearchListCriteria listCriteria = new SearchListCriteria();
				listCriteria.removeAllAttribute();
				listCriteria.setAttribute("userByUserId.id", new Object[] {user.getId(),listCriteria.EQ});
				listCriteria.setAttribute("flag", new Object[] {true,listCriteria.EQ});
				if(changeListStatus != 0){
					addListCriteriaByTime();
					listCriteria.setAttribute("createdOn", new Object[] {targetDate,listCriteria.GE});
				}
				mailList = MailServerDelegator.getConditionMailList(listCriteria);
			}
			mailList = Sort.byMailDate(mailList);
		}catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String showMailBox() throws Exception{
		if (logger.isDebugEnabled()) {
			logger.debug("showMailBox() - start"); //$NON-NLS-1$
		}

		if(request.getSession().getAttribute("actionMessage") != null) {
			Collection<String> coll = (Collection<String>) request.getSession().getAttribute("actionMessage");

			for (String aMessage : coll) {
				addActionMessage(aMessage);
			}

			request.getSession().setAttribute("actionMessage", null);
		}

		mailBox();

		if (logger.isDebugEnabled()) {
			logger.debug("showMailBox() - end"); //$NON-NLS-1$
		}
		return SUCCESS;
	}

	public void messageDetails() throws Exception{
		try{
			User user = SessionUtil.getUser(request);
			if(criterionList.size() > 0 ){
		    	criterionList.clear();
		    }
			criterionList.add(Restrictions.eq("userByUserId", user));
			criterionList.add(Restrictions.eq("id", messageId));
			List<MailServer> mailServerList = (List<MailServer>) CommonFunctionDelegator.getObjectsByCriterion(criterionList, null, null, MailServer.class);
			if(mailServerList.size() > 0){
				messageDetail = mailServerList.size() > 0 ? mailServerList.get(0) : null;
			}else{
				mailBox();
				addActionError("Error While getting message");
			}
		}catch (Exception e) {
			mailBox();
			addActionError("Error While getting message");
			e.printStackTrace();
		}
		if(messageDetail != null && messageDetail.getIsRead() == false){
			try{
				this.messageDetail.setIsRead(true);
				MailServerDelegator.updateMail(messageDetail);
			}catch (Exception e) {
				mailBox();
				addActionError("Error While getting message");
				e.printStackTrace();
			}
		}

		mailBox();
	}

	public String showMessage() throws Exception{
		if (logger.isDebugEnabled()) {
			logger.debug("showMessage() - start"); //$NON-NLS-1$
		}

		try{
			User user = SessionUtil.getUser(request);
			if(criterionList.size() > 0 ){
		    	criterionList.clear();
		    }
			criterionList.add(Restrictions.eq("userByUserId", user));
			criterionList.add(Restrictions.eq("id", messageId));
			List<MailServer> mailServerList = (List<MailServer>) CommonFunctionDelegator.getObjectsByCriterion(criterionList, null, null, MailServer.class);
			if(mailServerList.size() > 0){
				messageDetail = mailServerList.size() > 0 ? mailServerList.get(0) : null;
			}else{
				mailBox();
				addActionError("Error While getting message");
				return ERROR;
			}
		}catch (Exception e) {
			mailBox();
			addActionError("Error While getting message");
			e.printStackTrace();
			return INPUT;
		}
		if(messageDetail != null && messageDetail.getIsRead() == false){
			try{
				this.messageDetail.setIsRead(true);
				MailServerDelegator.updateMail(messageDetail);
			}catch (Exception e) {
				mailBox();
				addActionError("Error While getting message");
				e.printStackTrace();
				return INPUT;
			}
		}

		mailBox();

		if (logger.isDebugEnabled()) {
			logger.debug("showMessage() - end"); //$NON-NLS-1$
		}
		return SUCCESS;
	}

	public String deleteMessage() throws Exception{
		if (logger.isDebugEnabled()) {
			logger.debug("deleteMessage() - start"); //$NON-NLS-1$
		}

		try{
			messageDetail = MailServerDelegator.getMailDetail(messageId);
			MailServerDelegator.deleteMessage(messageDetail);
			mailBox();
			mailList = MailServerDelegator.getMailDetails(user.getId());

		}catch (Exception e) {
			addActionMessage("Error while Delete Message");
			e.printStackTrace();
		}

		if (logger.isDebugEnabled()) {
			logger.debug("deleteMessage() - end"); //$NON-NLS-1$
		}
		addActionMessage("Delete Message successfully");
		return SUCCESS;
	}

	public String flagMessage() throws Exception{
		if (logger.isDebugEnabled()) {
			logger.debug("flagMessage() - start"); //$NON-NLS-1$
		}

		try{
			messageDetail = MailServerDelegator.getMailDetail(messageId);
		}catch (Exception e) {
			e.printStackTrace();
		}

		if(messageDetail.getFlag() == false){
			try{
				this.messageDetail.setFlag(true);
				MailServerDelegator.updateMail(messageDetail);
				mailBox();
				mailList = MailServerDelegator.getMailDetails(user.getId());
			}catch (Exception e) {
				addActionMessage("Flag while Delete Message");
				e.printStackTrace();
			}
		}

		if (logger.isDebugEnabled()) {
			logger.debug("flagMessage() - end"); //$NON-NLS-1$
		}

		mailBox();

		addActionMessage("Flag Message successfully");
		return SUCCESS;
	}

	public String forwardMessage() throws Exception{
		if (logger.isDebugEnabled()) {
			logger.debug("forwardMessage() - start"); //$NON-NLS-1$
		}

		try{
			User user = SessionUtil.getUser(request);
			if(criterionList.size() > 0 ){
		    	criterionList.clear();
		    }
			criterionList.add(Restrictions.eq("userByUserId", user));
			criterionList.add(Restrictions.eq("id", messageId));
			List<MailServer> mailServerList = (List<MailServer>) CommonFunctionDelegator.getObjectsByCriterion(criterionList, null, null, MailServer.class);
			if(mailServerList.size() > 0){
				messageDetail = mailServerList.size() > 0 ? mailServerList.get(0) : null;
				MailingSystem mailingSystem = (MailingSystem) ActionContext.getContext().getApplication().get(AdminConstants.MAILING_OPTIONS);
				MailHelper mailHelper = new MailHelper(mailingSystem.getServerAddress(), mailingSystem.getServerUsername(), mailingSystem.getServerPassword());
				if(Validator.isMailAddress(messageDetail.getUserByUserId().getEmail())){
					MailServer forwardMail = new MailServer();
					mailHelper.sendMail(mailingSystem.getWebmasterEmailAddress(), messageDetail.getUserByUserId().getEmail(), messageDetail.getSubject(), messageDetail.getBody());
					forwardMail.setBody(messageDetail.getBody());
					forwardMail.setFlag(false);
					forwardMail.setIsRead(false);
					forwardMail.setStatus(1);
					forwardMail.setSubject(messageDetail.getSubject());
					forwardMail.setUserByFromId(messageDetail.getUserByUserId());
					MailServerDelegator.insertMail(forwardMail);
					this.messageDetail.setStatus(3);
					MailServerDelegator.updateMail(messageDetail);
					addActionMessage("sent message successfully");
					messageDetails();
				}
			}else{
				messageDetails();
				addActionError("Error While forward message please check your email address");
				return INPUT;
			}
		}catch (Exception e) {
			messageDetails();
			addActionError("Error While Forward message");
			e.printStackTrace();
			return INPUT;
		}

		if (logger.isDebugEnabled()) {
			logger.debug("forwardMessage() - end"); //$NON-NLS-1$
		}
		return SUCCESS;
	}

	public String updateMessage() throws Exception{
		if (request.getParameter("check_list") != null) {
			String[] checkedId = request.getParameterValues("check_list");
			if(request.getParameter("deleteMsg") != null && request.getParameter("deleteMsg").equalsIgnoreCase("delete")){
				for (String chkid : checkedId) {
					messageDetail = MailServerDelegator.getMailDetail(Integer.parseInt(chkid));
					MailServerDelegator.deleteMessage(messageDetail);
				}
				addActionMessage("Delete Message successfully");
			}else if(request.getParameter("gobtn") != null && request.getParameter("gobtn").equalsIgnoreCase("go")){
				if(changeStatus == 0){
					mailBox();
					addActionError("Please Select -Mark as-");
					return INPUT;
				}else if(changeStatus == 1){
					for (String chkid : checkedId) {
						try{
							messageDetail = MailServerDelegator.getMailDetail(Integer.parseInt(chkid));
							if(messageDetail.getIsRead() == false){
								this.messageDetail.setIsRead(true);
								MailServerDelegator.updateMail(messageDetail);
							}
						}catch (Exception e) {
							e.printStackTrace();
						}
					}
					addActionMessage("Message Mark as read successfully");
				}else if(changeStatus == 2){
					for (String chkid : checkedId) {
						try{
							messageDetail = MailServerDelegator.getMailDetail(Integer.parseInt(chkid));
							if(messageDetail.getIsRead() == true){
								this.messageDetail.setIsRead(false);
								MailServerDelegator.updateMail(messageDetail);
							}
						}catch (Exception e) {
							e.printStackTrace();
						}
					}
					addActionMessage("Message Mark as Unread successfully");
				}else if(changeStatus == 3){
					for (String chkid : checkedId) {
						try{
							messageDetail = MailServerDelegator.getMailDetail(Integer.parseInt(chkid));
							if(messageDetail.getFlag() == false){
								this.messageDetail.setFlag(true);
								MailServerDelegator.updateMail(messageDetail);
							}
						}catch (Exception e) {
							e.printStackTrace();
						}
					}
					addActionMessage("Message Mark as flag successfully");
				}else if(changeStatus == 4){
					for (String chkid : checkedId) {
						try{
							messageDetail = MailServerDelegator.getMailDetail(Integer.parseInt(chkid));
							if(messageDetail.getFlag() == true){
								this.messageDetail.setFlag(false);
								MailServerDelegator.updateMail(messageDetail);
							}
						}catch (Exception e) {
							e.printStackTrace();
						}
					}
					addActionMessage("Message Mark as Unflag successfully");
				}
			}
		}else {
			if(changeListStatus != 0){
				mailBox();
				return SUCCESS;
			}else{
				mailBox();
				addActionError("Please Select Message for Chanage Status");
				return INPUT;
			}
		}
		mailBox();
		request.getSession().setAttribute("actionMessage", getActionMessages());
		return SUCCESS;
	}

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public Integer getMessageId() {
		return messageId;
	}

	public void setMessageId(Integer messageId) {
		this.messageId = messageId;
	}

	public MailServer getMessageDetail() {
		return messageDetail;
	}

	public void setMessageDetail(MailServer messageDetail) {
		this.messageDetail = messageDetail;
	}

	public MessagingSystemCount getSystemCount() {
		return systemCount;
	}

	public void setSystemCount(MessagingSystemCount systemCount) {
		this.systemCount = systemCount;
	}

	public String getShow() {
		return show;
	}

	public void setShow(String show) {
		this.show = show;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public String getParameter() {
		return parameter;
	}

	public void setParameter(String parameter) {
		this.parameter = parameter;
	}

	public Date getTargetDate() {
		return targetDate;
	}

	public void setTargetDate(Date targetDate) {
		this.targetDate = targetDate;
	}
}
